1Writer 実行中タスク選択
2024/10/22
code:js
// ===== 今日日付のファイルを開く =====
var dir = 'Dropbox/vault/private/notes/'
var name = ''
var ext = '.md'
let leftPad = (digit) => {
let str = digit.toString()
return digit >=10 ? str : 0 + str;
}
function format(date){
var year = leftPad(date.getFullYear() % 10000);
var month = leftPad(date.getMonth() + 1);
var day = leftPad(date.getDate());
var date = year+'-'+month+'-'+day;
return date
}
var today = format(new Date())
newFilePath=dir+today+ext
// 今日日付のファイルを開く
editor.openFile(newFilePath, 'edit', call);
function call(){
// ===== ソート + 未完了タスク選択 =====
function sortTasksByTime() {
// ===== ソート =====
// ユーザーのテキストを取得
const text = editor.getText();
// 行ごとに分割
const lines = text.split("\n");
// セクション区切りの検出パターン("### 🗂️"で始まる行)
const sectionDelimiter = /^### 🗂️/;
// 時刻を含む行を検出するパターン(@HH:MM形式の時刻は除外)
const timePattern = /(?<!@)\b\d{1,2}:\d{2}\b/;
let sections = [];
let currentSection = { header: null, linesWithTime: [], linesWithoutTime: [] };
let beforeFirstSection = [];
let sectionMap = {}; // 時刻なし行とセクションのマッピング
// フラグ:最初のセクションが見つかったか
let foundFirstSection = false;
// 行をループしてセクションごとにまとめる
lines.forEach(line => {
if (sectionDelimiter.test(line)) {
foundFirstSection = true;
// 新しいセクションが始まる場合、前のセクションを保存
if (currentSection.header !== null) {
sections.push(currentSection);
}
// 新しいセクション開始
currentSection = { header: line, linesWithTime: [], linesWithoutTime: [] };
} else if (foundFirstSection) {
// 時刻があるかないかで分類
if (timePattern.test(line)) {
currentSection.linesWithTime.push(line);
} else {
currentSection.linesWithoutTime.push(line);
// マッピングに追加(時刻なし行をセクションに紐付け)
}
}
} else {
// 最初のセクションより前の行をそのまま保持
beforeFirstSection.push(line);
}
});
// 最後のセクションを保存
if (currentSection.header !== null) {
sections.push(currentSection);
}
// セクションと時刻ありの行をすべて集めて一つのリストに
let allItemsWithTime = [];
sections.forEach(section => {
if (timePattern.test(section.header)) {
allItemsWithTime.push({ line: section.header, isHeader: true });
}
section.linesWithTime.forEach(line => {
allItemsWithTime.push({ line: line, isHeader: false });
});
});
// 全ての時刻あり項目を時刻順にソート
allItemsWithTime.sort((a, b) => {
const timeA = a.line.match(timePattern)0; const timeB = b.line.match(timePattern)0; return timeA.localeCompare(timeB);
});
// ソート結果をセクションごとに整理して保持
let sortedSections = [];
let currentSortedSection = null;
allItemsWithTime.forEach(item => {
if (item.isHeader) {
// 新しいセクションが開始
if (currentSortedSection !== null) {
sortedSections.push(currentSortedSection);
}
currentSortedSection = { header: item.line, lines: [] };
} else {
// セクションに時刻あり行を追加
if (currentSortedSection !== null) {
currentSortedSection.lines.push(item.line);
}
}
});
// 最後のセクションも追加
if (currentSortedSection !== null) {
sortedSections.push(currentSortedSection);
}
// 時刻なしの行を、元のセクションに基づいて追加
sortedSections.forEach(section => {
const header = section.header;
// マッピングに基づいて、時刻なしの行をセクションの末尾に追加
section.lines.push(...sectionMapheader); }
});
// セクションごとのリストを結合して元のノートに戻す
sortedSections.forEach(section => {
result.push(section.header);
result.push(...section.lines);
});
// 結果をテキストに戻してエディターに設定
editor.setText(result.join("\n"));
// ===== カーソル合わせ =====
// ソート後、"- "で始まる行のうち一番上の行の末尾にカーソルを合わせる
const newContent = editor.getText();
const newLines = newContent.split('\n');
let position = 0;
for (let i = 0; i < newLines.length; i++) {
if (newLinesi.startsWith('- ')) { firstCheckboxLineIndex = i;
break;
}
position += newLinesi.length + 1; // +1 は改行の分を加味するため }
if (firstCheckboxLineIndex !== -1) {
// 行末にカーソルをセット
const lineEndPosition = position + line.length; // 行頭から行末までの位置
editor.setSelectedRange(lineEndPosition, 0); // カーソルの位置を行末に設定
} else {
ui.hudError('チェックボックス付きの行が見つかりませんでした');
}
}
// セクション内の行をソートする関数
function sortSection(sectionLines) {
const linesWithTime = [];
const linesWithoutTime = [];
sectionLines.forEach(line => {
// @hh:mm 形式は無視する
const timeMatch = line.match(/\b(?<!@)\d{2}:\d{2}\b/);
if (timeMatch) {
linesWithTime.push({ line, time: timeMatch0 }); } else {
linesWithoutTime.push(line);
}
});
// 時刻を持つ行を時刻順にソート
const sortedLinesWithTime = linesWithTime.sort((a, b) => {
return a.time.localeCompare(b.time);
}).map(item => item.line);
// ソートされた行とその他の行を結合して返す
}
// 関数を実行
sortTasksByTime();
}